import { http } from "@/utils/http";
import type { ApiResponse } from "../user";
import { ensureArray, normalisePagination, toNumber } from "@/api/_helpers";

const ACCOUNT_BASE = "/system/account";

export interface AccountListParams {
  page?: number;
  page_size?: number;
  keyword?: string;
  username?: string;
  phone?: string;
  status?: number | string;
  role_id?: number | string;
  org_id?: number | string;
  scope_type?: string;
}

export interface RoleSummary {
  id: number;
  name: string;
  code: string;
  scope_type?: string;
  status?: number;
}

export interface AccountItem {
  id: number;
  username: string;
  nickname?: string;
  real_name?: string;
  phone?: string;
  email?: string | null;
  status: number;
  avatar?: string | null;
  org_id?: number | null;
  org_name?: string | null;
  region_id?: number | null;
  region_name?: string | null;
  last_login_at?: string | null;
  created_at?: string | null;
  updated_at?: string | null;
  remark?: string | null;
  register_channel?: string | null;
  roles?: Array<RoleSummary>;
  [key: string]: any;
}

export interface AccountListResult {
  list: Array<AccountItem>;
  total: number;
  pageSize: number;
  currentPage: number;
  raw?: any;
}

export interface AccountPayload {
  phone: string;
  nickname?: string | null;
  real_name?: string | null;
  email?: string | null;
  password?: string;
  status?: number;
  role_ids?: Array<number>;
  remark?: string | null;
}

export interface AccountStatusPayload {
  status: number;
}

export interface AccountPasswordPayload {
  password: string;
}

const mapRoles = (input: unknown): Array<RoleSummary> => {
  const items = ensureArray<Record<string, any>>(input);
  return items
    .map(role => ({
      id: toNumber(role.id, 0),
      name: role.name ?? role.title ?? "",
      code: role.code ?? role.slug ?? role.identifier ?? "",
      scope_type: role.scope_type ?? role.type ?? undefined,
      status:
        role.status !== undefined && role.status !== null
          ? toNumber(role.status, 0)
          : undefined
    }))
    .filter(role => role.id > 0 || role.code || role.name);
};

const mapAccount = (item: Record<string, any>): AccountItem => {
  const profile = (item.profile ?? {}) as Record<string, any>;
  return {
    id: toNumber(item.id, 0),
    username: item.username ?? item.phone ?? "",
    nickname: profile.nickname ?? item.nickname ?? "",
    real_name: profile.real_name ?? item.real_name ?? item.name ?? "",
    phone: item.phone ?? "",
    email: item.email ?? null,
    status: toNumber(item.status, 0),
    avatar: profile.avatar ?? item.avatar ?? null,
    org_id: item.org_id ?? null,
    org_name: item.org_name ?? item.org?.name ?? null,
    region_id: item.region_id ?? null,
    region_name: item.region_name ?? item.region?.name ?? null,
    last_login_at:
      item.last_login_time ?? item.last_login_at ?? item.last_login ?? null,
    created_at: item.create_time ?? item.created_at ?? null,
    updated_at: item.update_time ?? item.updated_at ?? null,
    remark: item.remark ?? item.description ?? null,
    register_channel: item.register_channel ?? null,
    roles: mapRoles(item.roles)
  };
};

const mapListResponse = (
  payload: Record<string, any>,
  page: number,
  pageSize: number
): AccountListResult => {
  const listSource =
    payload.list ?? payload.data ?? payload.records ?? payload.items ?? [];
  const list = ensureArray<Record<string, any>>(listSource).map(mapAccount);
  const pagination = normalisePagination(
    payload.pagination ?? payload,
    page,
    pageSize,
    list.length
  );
  return {
    list,
    total: pagination.total,
    pageSize: pagination.pageSize,
    currentPage: pagination.currentPage,
    raw: payload
  };
};

const fetchList = async (
  params: AccountListParams = {}
): Promise<AccountListResult> => {
  const page = toNumber(params.page, 1);
  const pageSize = toNumber(params.page_size, 10);

  const query: Record<string, any> = {
    page,
    page_size: pageSize
  };

  if (params.status !== undefined && params.status !== "") {
    query.status = params.status;
  }

  if (params.role_id !== undefined && params.role_id !== "") {
    query.role_id = params.role_id;
  }

  if (params.scope_type) {
    query.scope_type = params.scope_type;
  }

  if (params.keyword) {
    query.keyword = params.keyword;
  } else if (params.username) {
    query.keyword = params.username;
  } else if (params.phone) {
    query.keyword = params.phone;
  }

  const response = await http.request<ApiResponse<any>>("get", ACCOUNT_BASE, {
    params: query
  });

  const payload = (response?.data as Record<string, any>) ?? {};
  return mapListResponse(payload, page, pageSize);
};

const create = async (payload: AccountPayload): Promise<AccountItem> => {
  const res = await http.request<ApiResponse<any>>("post", ACCOUNT_BASE, {
    data: payload
  });
  const data = (res?.data as Record<string, any>) ?? {};
  return mapAccount(data);
};

const update = async (
  id: number,
  payload: Partial<AccountPayload>
): Promise<AccountItem> => {
  const res = await http.request<ApiResponse<any>>(
    "put",
    `${ACCOUNT_BASE}/${id}`,
    {
      data: payload
    }
  );
  const data = (res?.data as Record<string, any>) ?? {};
  return mapAccount(data);
};

const remove = async (id: number): Promise<boolean> => {
  const res = await http.request<ApiResponse<any>>(
    "delete",
    `${ACCOUNT_BASE}/${id}`
  );
  if (typeof res?.data === "boolean") return res.data;
  if (res?.success !== undefined) return Boolean(res.success);
  return true;
};

const updateStatus = async (id: number, status: number): Promise<boolean> => {
  const res = await http.request<ApiResponse<any>>(
    "put",
    `${ACCOUNT_BASE}/${id}`,
    {
      data: { status }
    }
  );
  if (typeof res?.data === "boolean") return res.data;
  if (res?.success !== undefined) return Boolean(res.success);
  return true;
};

const resetPassword = async (
  id: number,
  payload: AccountPasswordPayload
): Promise<boolean> => {
  const res = await http.request<ApiResponse<any>>(
    "put",
    `${ACCOUNT_BASE}/${id}`,
    {
      data: { password: payload.password }
    }
  );
  if (typeof res?.data === "boolean") return res.data;
  if (res?.success !== undefined) return Boolean(res.success);
  return true;
};

export default {
  fetchList,
  create,
  update,
  remove,
  updateStatus,
  resetPassword
};
